package com.jsjvm.server.dbgproxy.jdwp.cmdsets;

import java.io.IOException;

import com.jsjvm.server.dbgproxy.JDWPCommandSet;
import com.jsjvm.server.dbgproxy.jdwp.data.JDWPInputStream;
import com.jsjvm.server.dbgproxy.jdwp.data.JDWPOutputStream;
import com.jsjvm.server.dbgproxy.jdwp.data.JDWPRequestHeader;
import com.jsjvm.shared.jdwp.data.JDWPLocation;
import com.jsjvm.shared.vmcmds.VMCommand;

@SuppressWarnings("serial")
public class JDWPEventRequestCommandSet extends JDWPCommandSet {
	private static final int EVENT_SET_CMD = 1;
	private static final int EVENT_CLEAR_CMD = 2;
	private static final int EVENT_CLEAR_BREAKPOINTS_CMD = 3;

	public static final int EVENT_REQUEST_SET = 15;

	@Override
	public int getCommandSetNumber() {
		return EVENT_REQUEST_SET;
	}

	public JDWPEventRequestCommandSet() {
		this.put(EVENT_SET_CMD, new EventSet());
	}

	// TODO : keep track of the requests and matching events
	private class EventSet extends JDWPCommandHandler {
		private int reqNo;
		private static final int CASE_COUNT = 1;
		private static final int CASE_CONDITIONAL = 2;
		private static final int CASE_THREAD_ONLY = 3;
		private static final int CASE_CLASS_ONLY = 4;
		private static final int CASE_CLASS_MATCH = 5;
		private static final int CASE_CLASS_EXCLUDE = 6;
		private static final int CASE_LOCATION_ONLY = 7;
		private static final int CASE_EXCEPTION_ONLY = 8;
		private static final int CASE_FIELD_ONLY = 9;
		private static final int CASE_STEP = 10;
		private static final int CASE_INSTANCE_ONLY = 11;
		private static final int CASE_SOURCE_NAME_MATCH = 12;

		@Override
		public VMCommand handleCommand(JDWPRequestHeader hdr, JDWPInputStream is,
				JDWPOutputStream os) throws IOException {
			byte eventKind = is.readByte();
			byte suspendPolicy = is.readByte();
			int modifiers = is.readInt();

			System.out.println("Event: " + eventKind + " " + modifiers + " "
					+ suspendPolicy);

			for (int i = 0; i < modifiers; i++) {
				byte modKind = is.readByte();
				System.out.println("modkind " + modKind);

				switch (modKind) {
				case CASE_COUNT: {
					int count = is.readInt();
					System.out.println("count = " + count);
					break;
				}

				case CASE_CONDITIONAL: {
					is.readInt();
					break;
				}
				case CASE_THREAD_ONLY: {
					int tid = is.readID();
					System.out.println("Thread ID = " + tid);
					break;
				}
				case CASE_CLASS_ONLY: {
					int classID = is.readID();
					System.out.println("Class ID = " + classID);
					break;
				}
				case CASE_CLASS_MATCH:
				case CASE_CLASS_EXCLUDE: {
					String classPat = is.readString();
					System.out.println("Class pattern = " + classPat);
					break;
				}
				case CASE_LOCATION_ONLY: {
					JDWPLocation l = is.readLocation();
					System.out.println("Location = " + l);
					break;
				}
				case CASE_EXCEPTION_ONLY: {
					int type = is.readID();
					byte caught = is.readByte();
					byte uncaught = is.readByte();

					System.out.println("type " + type
							+ (caught != 0 ? " cought " : "")
							+ (uncaught != 0 ? " uncought " : ""));
					break;
				}
				case CASE_FIELD_ONLY: {
					int cls = is.readID();
					int fld = is.readID();
					System.out.println("cls:field" + cls + ":" + fld);
					break;
				}
				case CASE_STEP: {
					int tid = is.readID();
					int size = is.readInt();
					int depth = is.readInt();
					System.out.println("Step in thread " + tid + " size "
							+ size + " depth " + depth);
					break;
				}
				case CASE_INSTANCE_ONLY: {
					int oid = is.readID();
					System.out.println("obj = " + oid);
					break;
				}
				case CASE_SOURCE_NAME_MATCH: {
					String pat = is.readString();
					System.out.println("pattern = " + pat);
					break;
				}
				}
			}

			os.appendInt(reqNo++);
			os.commitReplyPacket(hdr);
			return null;
		}
	}

}
